﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
// Copyright (C) 2021 kingerrobot
// 版权所有。 
//
// 文件名：BWmsOutOrderMaster
// 文件功能描述：
//
// 创建者：名字 (zzl)
// 时间：2021/12/21 15:55:51
//
// 修改人：
// 时间：
// 修改说明：
// 版本：V1.0.0
//----------------------------------------------------------------*/
#endregion
using System.Collections.Generic;
using System.Linq;
using K8.CBB;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using KingerRobot.MexicoSailunMDC.Dao;

namespace KingerRobot.MexicoSailunMDC.SpiService;

internal class BWarehousOut : IWarehousOut
{
    private readonly static ITask _Task = new BTask();
    private readonly static ITaskCmd _TaskCmd = new BTaskCmd();
    private readonly static IRcsEquipCuringDitch _RcsEquipCuringDitch = new BRcsEquipCuringDitch();
    private readonly static IWmsOutOrderSummary _WmsOutOrderSummary = new BWmsOutOrderSummary();
    private readonly static IWmsOutOrderMaster _WmsOutOrderMaster = new BWmsOutOrderMaster();
    private readonly static IWcsAsrsCrnOutPut _WcsAsrsCrnOutPut = new BWcsAsrsCrnOutPut();
    private readonly static IRcsEquipCrn _RcsEquipCrn = new BRcsEquipCrn();
    private readonly static IRcsLocation _RcsLocation = new BRcsLocation();
    private readonly static IWcsAsrsLocHalt _WcsAsrsLocHalt = new BWcsAsrsLocHalt();
    private readonly static IWcsEquipLocHold _WcsEquipLocHold = new BWcsEquipLocHold();
    private readonly static IWcsNetAbnormal _WcsNetAbnormal = new BWcsNetAbnormal();
    private readonly static IProdMaterial _ProdMaterial = new BProdMaterial();
    private readonly static IWms2MesService _Wms2MesService = new Wms2MesImpl();
    private readonly static IProdProduct _ProdProduct = new BProdProduct();
    private readonly static IWcsLocSku _WcsLocSku = new BWcsLocSku();
    private readonly static IWcsAsrsCrnAbnormalOutPut _WcsAsrsCrnAbnormalOutPut = new BWcsAsrsCrnAbnormalOutPut();

    public void SingleRoute(ref List<LocationInfo> startLocs,
        List<LocationGroupInfo> locationGroupInfos,
        POWmsOutOrderSummary summary,
        List<POWcsAsrsLocHalt> wcsAsrsLocHalts,
        List<CrnForkInfo> crnForkInfos)
    {
        // 一个有货 满足
        SingleGoods(ref startLocs, locationGroupInfos, wcsAsrsLocHalts, crnForkInfos, summary);

        if (startLocs.Count == 0)
        {
            // 两个有货，其中一个满足（物料不同，时间最早）
            DoubleDifferentSingleGoods(ref startLocs, locationGroupInfos, wcsAsrsLocHalts, crnForkInfos, summary);
        }

        if (startLocs.Count == 0)
        {
            // 两个有货，两个都满足（物料相同，时间最晚）
            DoubleSameDoubleGoods(ref startLocs, locationGroupInfos, null, wcsAsrsLocHalts, crnForkInfos, summary);
        }
    }

    public void DoubleDifferentGoodsRoute(ref List<LocationInfo> startLocs,

        List<LocationGroupInfo> locationGroupInfos,
        POWmsOutOrderSummary summary,
        List<POWcsAsrsLocHalt> wcsAsrsLocHalts,
        List<CrnForkInfo> crnForkInfos)
    {
        var count = startLocs.Count();
        if (startLocs.Count == count)
        {
            // 2、物料不相同双库位其中一个满足
            DoubleDifferentSingleGoods(ref startLocs, locationGroupInfos, wcsAsrsLocHalts, crnForkInfos, summary);
        }
        if (startLocs.Count == count)
        {
            // 3、单库位满足
            SingleGoods(ref startLocs, locationGroupInfos, wcsAsrsLocHalts, crnForkInfos, summary);
        }
        if (startLocs.Count == count)
        {
            // 4、两个双库位物料相同，各取一个
            DoubleSameDoubleGoods(ref startLocs, locationGroupInfos, null, wcsAsrsLocHalts, crnForkInfos, summary);
        }
    }

    public void DoubleSameGoodsRoute(ref List<LocationInfo> startLocs,
        List<LocationGroupInfo> locationGroupInfos,
        POWmsOutOrderSummary summary,
        List<POWcsAsrsLocHalt> wcsAsrsLocHalts,
        List<CrnForkInfo> crnForkInfos)
    {
        var count = startLocs.Count();
        // 1、物料不相同双库位其中一个满足
        DoubleDifferentSingleGoods(ref startLocs, locationGroupInfos, wcsAsrsLocHalts, crnForkInfos, summary);

        if (startLocs.Count == count)
        {
            // 2、单库位满足
            SingleGoods(ref startLocs, locationGroupInfos, wcsAsrsLocHalts, crnForkInfos, summary);
        }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="startLocs">已查找的取胎位</param>
    /// <param name="locs">满足当前物料规格库位</param>
    /// <param name="wcsAsrsLocHalts">停机库位</param>
    /// <param name="crnForkInfos">堆垛机货叉</param>
    /// <param name="summary">请料单</param>
    public void GetLocation(ref List<LocationInfo> startLocs,
        List<LocationInfo> locs,
        List<POWcsAsrsLocHalt> wcsAsrsLocHalts,
        List<CrnForkInfo> crnForkInfos,
        POWmsOutOrderSummary summary)
    {
        // 货叉
        var forkInfo1 = crnForkInfos.Where(t => t.IsEnable == true && t.Index == 1).FirstOrDefault();
        var forkInfo2 = crnForkInfos.Where(t => t.IsEnable == true && t.Index == 2).FirstOrDefault();
        var fork1 = forkInfo1 ?? forkInfo2;
        var fork2 = forkInfo2 ?? forkInfo1;

        var startLocCount = startLocs.Count;
        foreach (var loc in locs)
        {
            if (startLocCount == 0)
            {
                var fork = loc.GroupIndex == 1 ? fork1 : fork2; // 主负责货叉
                var isCrnFork = wcsAsrsLocHalts.Where(t => t.LocId == loc.Id && t.CrnFork == fork.Fork).Any();

                if (isCrnFork)
                {
                    fork = loc.GroupIndex == 1 ? fork2 : fork1; // 可替换货叉
                    isCrnFork = wcsAsrsLocHalts.Where(t => t.LocId == loc.Id && t.CrnFork == fork.Fork).Any();
                    if (isCrnFork)
                    {
                        continue;
                    }
                }

                // 查找货叉是否可以到达取货位
                var startLoc = loc;
                startLoc.Summary = summary;
                startLoc.Fork = fork;
                startLocs.Add(startLoc);
                break;

            }
            else
            {
                var useFork = startLocs.FirstOrDefault().Fork;  // 已配对货叉
                var useLoc = startLocs.FirstOrDefault().Id;     // 已配对货位
                var fork = crnForkInfos.Where(t => t.IsEnable == true && t.Fork != useFork.Fork).FirstOrDefault() ?? useFork; // 未配对货叉

                var isCrnFork = wcsAsrsLocHalts.Where(t => t.LocId == loc.Id && t.CrnFork == fork.Fork).Any();
                if (isCrnFork)
                {
                    if (fork.Fork == useFork.Fork)
                    {
                        // 单货叉
                        continue;
                    }

                    var emptyFork = fork;

                    var forkId = useFork.Fork;
                    var useForkId = emptyFork.Fork;
                    // 已配对货叉是否可以到达当前位置
                    isCrnFork = wcsAsrsLocHalts.Where(t => t.LocId == loc.Id && t.CrnFork == forkId).Any();
                    if (isCrnFork)
                    {
                        continue;
                    }

                    // 当前未配对货叉是否可以到达已配对位置
                    isCrnFork = wcsAsrsLocHalts.Where(t => t.LocId == useLoc && t.CrnFork == useForkId).Any();
                    if (isCrnFork)
                    {
                        continue;
                    }

                    // 交换货叉
                    fork = useFork;
                    useFork = emptyFork;
                }

                // 已配对重新配对
                startLocs.FirstOrDefault().Fork = useFork;

                // 新配对
                var startLoc = loc;
                startLoc.Summary = summary;
                startLoc.Fork = fork;
                startLocs.Add(startLoc);
                break;
            }
        }
    }


    /// <summary>
    /// 一个库位有料
    /// </summary>
    /// <param name="locationGroupInfos"></param>
    /// <param name="material"></param>
    /// <param name="materialId2"></param>
    /// <returns></returns>
    public void SingleGoods(ref List<LocationInfo> startLocs,
        List<LocationGroupInfo> locationGroupInfos,
        List<POWcsAsrsLocHalt> wcsAsrsLocHalts,
        List<CrnForkInfo> crnForkInfos,
        POWmsOutOrderSummary material)
    {

        var ids = startLocs.Select(t => t.Id).ToList();

        var materialId = material.MaterialId;

        var locations = locationGroupInfos.Where(t => t.MaterialId == materialId).FirstOrDefault()
                       .LocationInfos;
        if (locations is null)
        {
            WriteLog($"没有找到{materialId}物料库位2", true);
            return;
        }
        var locs = locations.Where(t => !ids.Contains(t.Id) && t.IsDouble == false)
                  .OrderBy(t => t.MdTime)
                  .ToList();

        // 判断货叉是否可以到达货位
        GetLocation(ref startLocs, locs, wcsAsrsLocHalts, crnForkInfos, material);
    }
    /// <summary>
    /// 一个库位有料（超8小时库存时限）
    /// </summary>
    /// <param name="locationGroupInfos"></param>
    /// <param name="material"></param>
    /// <param name="materialId2"></param>
    /// <returns></returns>
    public void SingleGoodsLimit(ref List<LocationInfo> startLocs,
        List<LocationGroupInfo> locationGroupInfos,
        List<POWcsAsrsLocHalt> wcsAsrsLocHalts,
        List<CrnForkInfo> crnForkInfos,
        POWmsOutOrderSummary material)
    {
        var ids = startLocs.Select(t => t.Id).ToList();
        var materialId = material.MaterialId;
        var locations = locationGroupInfos.Where(t => t.MaterialId == materialId).FirstOrDefault()
                       .LocationInfos;

        var locs = locations.Where(t => !ids.Contains(t.Id))
                  .OrderBy(t => t.MdTime)
                  .ToList();

        // 判断货叉是否可以到达货位
        GetLocation(ref startLocs, locs, wcsAsrsLocHalts, crnForkInfos, material);
    }

    /// <summary>
    /// 两个库位有料，物料不同,取一个
    /// </summary>
    /// <param name="locationGroupInfos"></param>
    /// <param name="materialId1"></param>
    /// <param name="materialId2"></param>
    /// <returns></returns>
    public void DoubleDifferentSingleGoods(ref List<LocationInfo> startLocs,

        List<LocationGroupInfo> locationGroupInfos,
        List<POWcsAsrsLocHalt> wcsAsrsLocHalts,
        List<CrnForkInfo> crnForkInfos,
        POWmsOutOrderSummary summary)
    {
        var ids = startLocs.Select(t => t.Id).ToList();
        var materialId = summary.MaterialId;
        var locations = locationGroupInfos.Where(t => t.MaterialId == materialId).FirstOrDefault().LocationInfos;
        if (locations is null)
        {
            WriteLog($"没有找到{materialId}物料库位1", true);
            return;
        }
        var locGroups = locations.Where(t => t.IsDouble == true)
                     .GroupBy(t => new { t.GroupId })
                     .Where(t => t.Count() == 1)
                     .Select(s => s.Key.GroupId)
                     .ToList();
        if (locGroups.Any())
        {
            var locs = locations
                .Where(t => !ids.Contains(t.Id) && locGroups.Contains(t.GroupId))
                .OrderBy(t => t.MdTime)
                .ToList();

            // 判断货叉是否可以到达货位
            GetLocation(ref startLocs, locs, wcsAsrsLocHalts, crnForkInfos, summary);
        }
    }

    /// <summary>
    /// 两个库位油料，物料相同,取一个或两个
    /// </summary>
    /// <param name="locationGroupInfos"></param>
    /// <param name="materialId1"></param>
    /// <param name="materialId2"></param>
    /// <returns></returns>
    public void DoubleSameDoubleGoods(ref List<LocationInfo> startLocs,
        List<LocationGroupInfo> locationGroupLimitInfos,
        List<LocationGroupInfo> locationGroupInfos,
        List<POWcsAsrsLocHalt> wcsAsrsLocHalts,
        List<CrnForkInfo> crnForkInfos,
        POWmsOutOrderSummary summary1,
        POWmsOutOrderSummary summary2 = null)
    {
        var ids = startLocs.Select(t => t.Id).ToList();
        var materialId1 = summary1.MaterialId;

        var locations = locationGroupLimitInfos.Where(t => t.MaterialId == materialId1).FirstOrDefault()?
                       .LocationInfos;

        if (locations is null)
        {
            WriteLog($"没有找到{materialId1}物料库位3", true);
            return;
        }

        var locGroups = locations.Where(t => t.IsDouble == true)
                     .GroupBy(t => new { t.GroupId })
                     .Where(t => t.Count() == 2)
                     .Select(s => s.Key.GroupId)
                     .Distinct()
                     .ToList();

        if (locGroups.Any())
        {
            if (summary2 != null)
            {
                // 货叉
                var forkInfo1 = crnForkInfos.Where(t => t.IsEnable == true && t.Index == 1).FirstOrDefault();
                var forkInfo2 = crnForkInfos.Where(t => t.IsEnable == true && t.Index == 2).FirstOrDefault();
                var fork1 = forkInfo1 ?? forkInfo2;
                var fork2 = forkInfo2 ?? forkInfo1;

                foreach (var locGroup in locGroups)
                {
                    var startLoc1 = locations.Where(t => t.GroupId == locGroup && t.GroupIndex == 1)
                        .OrderBy(t => t.MdTime).FirstOrDefault();
                    if (startLoc1 is null)
                    {
                        WriteLog($"没有找到{materialId1},startLoc1物料库位", true);
                        continue;
                    }

                    startLoc1.Fork = startLoc1.GroupIndex == 1 ? fork1 : fork2;
                    startLoc1.Summary = startLoc1.GroupIndex == 1 ? summary1 : summary2;

                    var startLoc2 = locationGroupInfos.Where(t => t.MaterialId == materialId1).FirstOrDefault().LocationInfos
           .Where(t => t.GroupId == startLoc1.GroupId && t.Id != startLoc1.Id).FirstOrDefault();
                    if (startLoc2 is null)
                    {

                        //WriteLog($"没有找到{materialId1},startLoc2物料库位,另一个货位{startLocs.ToJson()}", true);
                        continue;
                    }

                    startLoc2.Fork = startLoc2.GroupIndex == 1 ? fork1 : fork2;
                    startLoc2.Summary = startLoc2.GroupIndex == 1 ? summary1 : summary2;

                    startLocs.Add(startLoc1);
                    startLocs.Add(startLoc2);

                    break;
                }
            }
            else
            {
                var locs = locations
                    .Where(t => !ids.Contains(t.Id) && locGroups.Contains(t.GroupId))
                    //.OrderByDescending(t => t.MdTime)
                    .OrderBy(t => t.MdTime)
                    .ToList();

                // 判断货叉是否可以到达货位
                GetLocation(ref startLocs, locs, wcsAsrsLocHalts, crnForkInfos, summary1);
            }
        }
    }


    /// <summary>
    /// 两个库位有料，物料不同，取两个
    /// </summary>
    /// <param name="locationGroupInfos"></param>
    /// <param name="summary1"></param>
    /// <param name="summary2"></param>
    /// <returns></returns>
    public void DoubleDifferentDoubleGoodsV2(ref List<LocationInfo> startLocs,
        List<LocationGroupInfo> locationGroupLimitInfos,
        List<LocationGroupInfo> locationGroupInfos,
        List<CrnForkInfo> crnForkInfos,
        POWmsOutOrderSummary summary1,
        POWmsOutOrderSummary summary2,
        List<POWcsAsrsLocHalt> wcsAsrsLocHalts)
    {
        var materialId1 = summary1.MaterialId;
        var materialId2 = summary2.MaterialId;
        var materialIds = new List<long?>()
        {
            summary1.MaterialId,
            summary2.MaterialId
        };

        //获取双胎库位 但是只有一个胎是1#物料的库位组
        var locSingleGroups = locationGroupLimitInfos.Where(t => t.MaterialId == materialId1).FirstOrDefault()
                        .LocationInfos.Where(t => t.IsDouble == true)
                        .GroupBy(t => new { t.GroupId })
                        .Where(t => t.Count() == 1)
                        .Select(s => s.Key.GroupId)
                        .ToList();

        // 满足出库物料货位
        var locations = locationGroupInfos.Where(t => materialIds.Contains(t.MaterialId)).SelectMany(t => t.LocationInfos).ToList();
        // 满足出库物料双货位
        var locDopubleGroups = locations.Where(t => t.IsDouble == true)
                     .GroupBy(t => new { t.GroupId })
                     .Where(t => t.Count() == 2)
                     .Select(s => s.Key.GroupId)
                     .ToList();

        // 找到两个货位有胎，并且物料不同，满足出库条件
        var locGroups = locSingleGroups.Intersect(locDopubleGroups);


        if (locGroups.Any())
        {
            // 货叉
            var forkInfo1 = crnForkInfos.Where(t => t.IsEnable == true && t.Index == 1).FirstOrDefault();
            var forkInfo2 = crnForkInfos.Where(t => t.IsEnable == true && t.Index == 2).FirstOrDefault();
            var fork1 = forkInfo1 ?? forkInfo2;
            var fork2 = forkInfo2 ?? forkInfo1;

            var startLocAlls = locations.Where(t => locGroups.Contains(t.GroupId)).OrderBy(t => t.MdTime).ToList();
            var goups = startLocAlls.Select(t => t.GroupId).Distinct().ToList();

            foreach (var group in goups)
            {
                // 第一个取货位
                var startLoc1 = startLocAlls.Where(t => t.GroupId == group && t.GroupIndex == 1).FirstOrDefault();
                // 第二个取货位
                var startLoc2 = startLocAlls.Where(t => t.GroupId == startLoc1.GroupId && t.Id != startLoc1.Id).FirstOrDefault();

                if (startLoc1 is null || startLoc2 is null)
                {
                    continue;
                }

                if (startLoc1.MaterialId == summary1.MaterialId)
                {
                    startLoc1.Summary = summary1;
                    startLoc2.Summary = summary2;
                }
                else
                {
                    // 验证停机货位
                    startLoc1.Summary = summary2;
                    startLoc2.Summary = summary1;
                }
                startLoc1.Fork = startLoc1.GroupIndex == 1 ? fork1 : fork2;
                startLoc2.Fork = startLoc2.GroupIndex == 1 ? fork1 : fork2;

                // 判断货叉是否可以
                var isCrnForkA = wcsAsrsLocHalts.Where(t => t.LocId == startLoc1.Summary.TargetLoc && t.CrnFork == startLoc1.Fork.Fork).Any();
                var isCrnForkB = wcsAsrsLocHalts.Where(t => t.LocId == startLoc2.Summary.TargetLoc && t.CrnFork == startLoc2.Fork.Fork).Any();
                if (isCrnForkA || isCrnForkB)
                {
                    continue;
                }
                startLocs.Add(startLoc1);
                startLocs.Add(startLoc2);
            }
        }

    }
    /// <summary>
    /// 物料不同，取两个（超出8小时限时的库存）
    /// </summary>
    /// <param name="locationGroupInfos"></param>
    /// <param name="materialId1"></param>
    /// <param name="materialId2"></param>
    /// <returns></returns>
    public void DoubleDifferentLimit(ref List<LocationInfo> startLocs,
        List<LocationGroupInfo> locationGroupInfos,
        List<POWcsAsrsLocHalt> wcsAsrsLocHalts,
        List<CrnForkInfo> crnForkInfos,
        POWmsOutOrderSummary material1,
        POWmsOutOrderSummary material2, DateTime limitTime)
    {
        // 物料
        var materialId1 = material1.MaterialId;
        var materialId2 = material2.MaterialId;
        var materialIds = new List<long?>()
        {
            materialId1,
            materialId2
        };

        // 货位
        var locations = locationGroupInfos.Where(t => materialIds.Contains(t.MaterialId)).SelectMany(t => t.LocationInfos).ToList();
        var locmater1 = locationGroupInfos.Where(t => t.MaterialId == materialId1).OrderBy(t => t.MinTime);
        var startLoc1 = new LocationInfo();
        var startLoc2 = new LocationInfo();

        // 货叉
        var forkInfo1 = crnForkInfos.Where(t => t.IsEnable == true && t.Index == 1).FirstOrDefault();
        var forkInfo2 = crnForkInfos.Where(t => t.IsEnable == true && t.Index == 2).FirstOrDefault();
        var fork1 = forkInfo1 ?? forkInfo2;
        var fork2 = forkInfo2 ?? forkInfo1;

        //验证是不是第一个物料存在超期库存
        if (!locmater1.Where(t => t.MinTime < limitTime).Any())
        {
            var locmater2 = locationGroupInfos.Where(t => t.MaterialId == materialId2).OrderBy(t => t.MinTime);
            var totalLocs = locmater2.SelectMany(t => t.LocationInfos).OrderBy(t => t.MdTime).ToList();

            foreach (var loc in totalLocs)
            {
                startLoc2 = loc;
                startLoc2.Fork = startLoc2.GroupIndex == 1 ? fork1 : fork2;
                startLoc2.Summary = startLoc2.GroupIndex == 1 ? material1 : material2;

                var isCrnFork1 = wcsAsrsLocHalts.Where(t => t.LocId == startLoc2.Summary.TargetLoc && t.CrnFork == startLoc2.Fork.Fork).Any();
                if (isCrnFork1)
                {
                    continue;
                }
                //判断当前库位同一组下的另一个库位物料是否符合
                var startLoc2other = locations.Where(t => t.GroupId == startLoc2.GroupId && t.GroupIndex != startLoc2.GroupIndex).FirstOrDefault();

                POWmsOutOrderSummary summary = startLoc2.Summary.Id == material1.Id ? material2 : material1;
                var materialId = summary.MaterialId;

                if (startLoc2other != null && startLoc2other.MaterialId == materialId)
                {
                    startLoc1 = startLoc2other;
                    startLoc1.Fork = startLoc1.GroupIndex == 1 ? fork1 : fork2;
                    startLoc1.Summary = startLoc1.GroupIndex == 1 ? material1 : material2;

                    var isCrnFork2 = wcsAsrsLocHalts.Where(t => t.LocId == startLoc1.Summary.TargetLoc && t.CrnFork == startLoc1.Fork.Fork).Any();
                    if (isCrnFork2)
                    {
                        continue;
                    }

                    startLocs.Add(startLoc2);
                    startLocs.Add(startLoc1);
                }
                else
                {
                    locationGroupInfos = locationGroupInfos.Where(t => t.CrnId == startLoc2.CrnId).ToList();
                    startLocs.Add(startLoc2);
                    //寻找单胎库位物料
                    SingleGoodsLimit(ref startLocs, locationGroupInfos, wcsAsrsLocHalts, crnForkInfos, summary);
                }
                break;
            }

        }
        else
        {

            var totalLocs = locmater1.SelectMany(t => t.LocationInfos).OrderBy(t => t.MdTime).ToList();

            foreach (var loc in totalLocs)
            {
                startLoc1 = loc;

                startLoc1.Fork = startLoc1.GroupIndex == 1 ? fork1 : fork2;
                startLoc1.Summary = startLoc1.GroupIndex == 1 ? material1 : material2;
                var isCrnFork1 = wcsAsrsLocHalts.Where(t => t.LocId == startLoc1.Summary.TargetLoc && t.CrnFork == startLoc1.Fork.Fork).Any();
                if (isCrnFork1)
                {
                    continue;
                }

                var startLoc1other = locations.Where(t => t.GroupId == startLoc1.GroupId && t.GroupIndex != startLoc1.GroupIndex).FirstOrDefault();

                POWmsOutOrderSummary summary = startLoc1.Summary.Id == material1.Id ? material2 : material1;
                var materialId = summary.MaterialId;

                if (startLoc1other != null && startLoc1other.MaterialId == materialId)
                {
                    startLoc2 = startLoc1other;
                    startLoc2.Fork = startLoc2.GroupIndex == 1 ? fork1 : fork2;
                    startLoc2.Summary = startLoc2.GroupIndex == 1 ? material1 : material2;
                    var isCrnFork2 = wcsAsrsLocHalts.Where(t => t.LocId == startLoc2.Summary.TargetLoc && t.CrnFork == startLoc2.Fork.Fork).Any();
                    if (isCrnFork2)
                    {
                        continue;
                    }

                    startLocs.Add(startLoc1);
                    startLocs.Add(startLoc2);
                }
                else
                {


                    locationGroupInfos = locationGroupInfos.Where(t => t.CrnId == startLoc1.CrnId).ToList();
                    startLocs.Add(startLoc1);
                    //寻找单胎库位物料
                    SingleGoodsLimit(ref startLocs, locationGroupInfos, wcsAsrsLocHalts, crnForkInfos, summary);
                }
                break;
            }
        }
    }
    /// <summary>
    /// 相同物料存在超过8小时时限的库存
    /// </summary>
    /// <param name="startLocs">返回的库位</param>
    /// <param name="locationGroupInfos"></param>
    /// <param name="wcsAsrsLocHalts"></param>
    /// <param name="crnForkInfos"></param>
    /// <param name="summary1"></param>
    /// <param name="summary2"></param>
    /// <param name="limitTime"></param>
    public void DoubleSameLimit(ref List<LocationInfo> startLocs,
     List<LocationGroupInfo> locationGroupInfos,
     List<POWcsAsrsLocHalt> wcsAsrsLocHalts,
     List<CrnForkInfo> crnForkInfos,
     POWmsOutOrderSummary summary1,
     POWmsOutOrderSummary summary2, DateTime limitTime)
    {
        // 货位
        var materialId1 = summary1.MaterialId;
        var locmater1 = locationGroupInfos.Where(t => t.MaterialId == materialId1).OrderBy(t => t.MinTime);
        var startLoc1 = new LocationInfo();
        var startLoc2 = new LocationInfo();

        // 货叉
        var forkInfo1 = crnForkInfos.Where(t => t.IsEnable == true && t.Index == 1).FirstOrDefault();
        var forkInfo2 = crnForkInfos.Where(t => t.IsEnable == true && t.Index == 2).FirstOrDefault();
        var fork1 = forkInfo1 ?? forkInfo2;
        var fork2 = forkInfo2 ?? forkInfo1;

        //验证是不是第一个物料存在超期库存
        if (!locmater1.Any())
        {
            return;
        }
        var totalLocs = locmater1.FirstOrDefault().LocationInfos;
        foreach (var loc in totalLocs)
        {
            startLoc1 = loc;
            startLoc1.Fork = startLoc1.GroupIndex == 1 ? fork1 : fork2;
            startLoc1.Summary = startLoc1.GroupIndex == 1 ? summary1 : summary2;
            var isCrnFork1 = wcsAsrsLocHalts.Where(t => t.LocId == startLoc1.Summary.TargetLoc && t.CrnFork == startLoc1.Fork.Fork).Any();
            if (isCrnFork1)
            {
                continue;
            }


            var otherLoc = totalLocs.Where(x => x.GroupIndex != startLoc1.GroupIndex && x.GroupId == startLoc1.GroupId).FirstOrDefault();

            POWmsOutOrderSummary summary = startLoc1.Summary.Id == summary1.Id ? summary2 : summary1;
            var materialId = summary.MaterialId;

            if (otherLoc != null && otherLoc.MaterialId == materialId)
            {
                startLoc2 = otherLoc;
                startLoc2.Fork = startLoc2.GroupIndex == 1 ? fork1 : fork2;
                startLoc2.Summary = startLoc2.GroupIndex == 1 ? summary1 : summary2;

                var isCrnFork2 = wcsAsrsLocHalts.Where(t => t.LocId == startLoc2.Summary.TargetLoc && t.CrnFork == startLoc2.Fork.Fork).Any();
                if (isCrnFork2)
                {
                    continue;
                }

                startLocs.Add(startLoc1);
                startLocs.Add(startLoc2);
            }
            else
            {


                locationGroupInfos = locationGroupInfos.Where(t => t.CrnId == startLoc1.CrnId).ToList();

                startLocs.Add(startLoc1);
                SingleGoodsLimit(ref startLocs, locationGroupInfos, wcsAsrsLocHalts, crnForkInfos, summary);
            }
            break;
        }
    }

    //创建任务  堆垛机货叉路线信息，出库路线，出库站台，货车停机货位，出库订单，库位，限制时间
    public List<WcsAsrsNetOutputGroup> CreateTaskLimit(List<WcsAsrsNetOutputGroup> asrsOutInfoBeans, List<NetOutEntity> asrsNetOutputs, List<CrnOutLoc> platformLocs,
        List<POWcsAsrsLocHalt> wcsAsrsLocHalts, OrderSummaryGroupyMaster master, DateTime limitTime)
    {
        var summaryids = master.POWmsOutOrderSummaries.Select(t => t.Id.GetValueOrDefault()).ToList();
        var newDate = DateTime.Now;

        var crnIds = platformLocs.Select(t => t.CrnId).ToList();
        var areaIds = platformLocs.Select(t => t.AreaId).ToList();
        var netOutputs = asrsNetOutputs.Where(t => crnIds.Contains(t.CrnId) && areaIds.Contains(t.AreaId)).ToList();

        if (netOutputs.Count == 0)
        {
            _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, $"过期,站台位数量{platformLocs.Count}[可能堆垛机出库任务满],没有可选择出库路线 | {newDate}.");

            //WriteLog($"过期,站台位数量{platformLocs.Count}[可能堆垛机出库任务满],没有可选择出库路线{newDate}.数据：{platformLocs.ToJson()}", true);
            return asrsOutInfoBeans;
        }

        foreach (var wcsAsrsNet in netOutputs)
        {
            if (wcsAsrsNet.LocationGroupInfos.Count() == 0)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, $"过期,没有满足的库位可能 | {newDate}");
                continue;
            }

            // 站台位是否空
            var noSkuLoc = platformLocs.Where(t => t.AreaId == wcsAsrsNet.AreaId && t.CrnId == wcsAsrsNet.CrnId).FirstOrDefault();
            if (noSkuLoc == null)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, $"过期,堆垛机{wcsAsrsNet.CrnId}出库站台位未找到,可能出库任务数已满 | {newDate}.");

                //WriteLog($"未过期,{wcsAsrsNet.AreaId},{wcsAsrsNet.CrnId}出库站台位{platformLocs.Count}未找到{newDate},数据：{platformLocs.ToJson()}", true);

                continue;
            }

            // 站台
            var loc1 = noSkuLoc.ExLocInfos.Where(t => t.Index == 1).FirstOrDefault();
            var loc2 = noSkuLoc.ExLocInfos.Where(t => t.Index == 2).FirstOrDefault();

            // 查询数量任务数量
            var taskCount = _TaskCmd.GetTaskCmdCountByLocs(new()
            {
                loc1.LocId.GetValueOrDefault(),
                loc2.LocId.GetValueOrDefault()
            });
            if (taskCount >= noSkuLoc.TaskCount)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, $"过期,出库任务数{taskCount}>={noSkuLoc.TaskCount}已满 | {newDate}");
                continue;
            }

            var crnForkInfos = wcsAsrsNet.NetOutPut.CrnForkInfo; // 货叉【可用、不可用都包含】

            // 获取取货位
            var startLocs = new List<LocationInfo>();
            var orderSummaries = master.POWmsOutOrderSummaries.OrderBy(t => t.SummaryIndex).ToList();

            var summaryCount = orderSummaries.Count;

            var material1 = orderSummaries.FirstOrDefault();
            var material2 = orderSummaries.LastOrDefault();

            var materialId1 = material1?.MaterialId;
            var materialId2 = material2?.MaterialId;

            //OLDTODO 两个货叉可用，同时去两个不成对立库取货，可能有一个货位 货叉过不去。
            if (summaryCount == 1)
            {
                SingleGoodsLimit(ref startLocs, wcsAsrsNet.LocationGroupInfos, wcsAsrsLocHalts, crnForkInfos, material1);
            }
            else if (summaryCount == 2)
            {
                if (materialId1 != materialId2)
                {
                    DoubleDifferentLimit(ref startLocs, wcsAsrsNet.LocationGroupInfos, wcsAsrsLocHalts, crnForkInfos, material1, material2, limitTime);

                }
                else
                {
                    DoubleSameLimit(ref startLocs, wcsAsrsNet.LocationGroupInfos, wcsAsrsLocHalts, crnForkInfos, material1, material2, limitTime);
                }
            }

            if (startLocs.Count != summaryCount)
            {
                var prodMaterial = _ProdMaterial.GetMaterialById(materialId1.GetValueOrDefault());
                var spec = prodMaterial?.Spec;
                prodMaterial = _ProdMaterial.GetMaterialById(materialId2.GetValueOrDefault());
                var spec1 = prodMaterial?.Spec;

                _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, $"过期,{spec},{spec1}满足出库货位{startLocs.Count} 与请料单数量{summaryCount}不一致 | {newDate}");
                continue;
            }

            var message = "";
            // 判断是否能到 27 列
            for (var i = 0; i < startLocs.Count; i++)
            {
                var flag = wcsAsrsLocHalts.Where(t => t.LocId == startLocs[i].Id && t.CrnFork == startLocs[i].Fork.Fork).Any();
                if (flag)
                {
                    message += $"过期,停机货位：{wcsAsrsLocHalts.Count}货叉{startLocs[i].Fork.Fork}无法到达货位{startLocs[i].Id} ———";
                }
            }
            if (!string.IsNullOrWhiteSpace(message))
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, $"提示:{message} | {newDate}");
                continue;
            }


            // 创建任务
            var taskBeans = new List<TaskBean>();
            startLocs = startLocs.OrderBy(t => t.GroupIndex).ToList(); // 排序五种情况 (2),(1),(1,2),(1,1),(2,2)

            var groupNo = K8.LSF.Client.CodeValue(new DateTime(), "GroupNo").ToInt(0);
            var forkCount = crnForkInfos.Where(t => t.IsEnable == true).Count(); // 可用货叉数

            for (var i = 0; i < startLocs.Count; i++)
            {
                // 放胎位
                var loc = startLocs[i].Fork.Index == 1 ? loc1 : loc2;

                if (forkCount == 1 && i == 1)
                {
                    // 单货叉可用
                    groupNo = K8.LSF.Client.CodeValue(new DateTime(), "GroupNo").ToInt(0);
                }

                taskBeans.Add(new()
                {
                    StartLoc = startLocs[i].Id,
                    CmdTargetLoc = loc.LocId.GetValueOrDefault(),
                    TaskTargetLoc = startLocs[i].Summary.TargetLoc,
                    Fork = startLocs[i].Fork,
                    MasterId = startLocs[i].Summary.MasterId,
                    SummaryId = startLocs[i].Summary.Id,
                    Index = startLocs[i].Summary.SummaryIndex,
                    GroupNo = groupNo,
                });
            }

            // 创建任务
            var taskIds = new List<long>();
            foreach (var item in taskBeans)
            {
                var taskId = CreateTask(item);
                if (taskId <= 0)
                {
                    _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { item.SummaryId.GetValueOrDefault() }, $"任务创建失败({taskId}) | {newDate}");
                    break;
                }
                taskIds.Add(taskId);
            }
            if (taskIds.Count > 0)
            {

                // 修改可执行状态状态
                _Task.UpdateTaskAndCmdStatusByTaskIds(taskIds, (int)EnumTaskStatus.Executable);
                var forks = startLocs.Select(t => t.Fork.Fork).ToList();

                //OLDTODO删除 (包含 fork1, fork2 货叉) 可用堆垛机出库路线
                var deletes = asrsOutInfoBeans.Where(t => t.CrnForkInfo.Select(x => forks.Contains(x.Fork)).Any()).ToList();
                deletes.ForEach(t =>
                {
                    asrsOutInfoBeans.Remove(t);
                });

                break;
            }
        }

        //OLDTODO 单货叉超期无法出库，不超期逻辑（创建成功返回 true ,创建失败返回 false,查找未超期胎胚）

        return asrsOutInfoBeans;
    }
    public void CreateTaskByLocOrder(OrderSummaryGroupyMaster master, List<CrnForkInfo> crnForks)
    {
        var crnList = _RcsEquipCrn.GetRcsEquipCrn();
        var equipHoldList = _WcsEquipLocHold.GetEquipLocHolds();
        var equipHaltList = _WcsAsrsLocHalt.GetAsrsLocHalt();
        var taskBeans = new List<TaskBean>();
        foreach (var summary in master.POWmsOutOrderSummaries)
        {
            var equipHold = equipHoldList.Where(t => t.LocId == summary.StartLoc).FirstOrDefault();
            if (equipHold == null)
            {
                continue;
            }
            var crn = crnList.Where(t => t.Id == equipHold.EquipId).FirstOrDefault();
            if (crn == null)
            {
                continue;
            }
            var equipHalt = equipHaltList.Where(t => t.LocId == summary.StartLoc).FirstOrDefault();
            var fork = new CrnForkInfo();
            if (equipHalt != null)
            {
                if (crnForks.Where(t => t.Fork == equipHalt.CrnFork).Count() == 0)
                {
                    break;
                }
                fork = crnForks.Where(t => t.Fork != equipHalt.CrnFork && t.CrnId == crn.Id).FirstOrDefault();

            }
            else
            {
                if (crnForks.Where(t => t.Fork == crn.CrnFork1).Count() == 0)
                {
                    if (crnForks.Where(t => t.Fork == crn.CrnFork2).Count() == 0)
                    {
                        break;
                    }
                    else
                    {
                        fork = crnForks.Where(t => t.Fork == crn.CrnFork2).FirstOrDefault();
                    }
                }
                else
                {
                    fork = crnForks.Where(t => t.Fork == crn.CrnFork1).FirstOrDefault();
                }
            }
            //获得当前堆垛机

            taskBeans.Add(new()
            {
                StartLoc = summary.StartLoc,
                CmdTargetLoc = summary.TargetLoc,
                TaskTargetLoc = summary.TargetLoc,
                Fork = fork,
                MasterId = summary.MasterId,
                SummaryId = summary.Id,
                Index = summary.SummaryIndex,
                GroupNo = K8.LSF.Client.CodeValue(new DateTime(), "GroupNo").ToInt(0)
            });
        }
        var taskIds = new List<long>();
        foreach (var item in taskBeans)
        {
            var taskId = CreateTask(item);
            if (taskId <= 0)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { item.SummaryId.GetValueOrDefault() }, $"任务创建失败({taskId}) | {DateTime.Now}");
                break;
            }
            taskIds.Add(taskId);
        }
        if (taskIds.Count > 0)
        {

            // 修改可执行状态状态
            _Task.UpdateTaskAndCmdStatusByTaskIds(taskIds, (int)EnumTaskStatus.Executable);


        }
    }
    public void CreateTaskSigleOrders(OrderSummaryGroupyMaster master, CrnForkInfo crnFork,
        List<PORcsLocation> bRcsLocations, List<POWcsAsrsLocHalt> pOWcsAsrsLocHalts, List<long?> locSkuIds)
    {
        var taskBeans = new List<TaskBean>();
        DateTime newDate = DateTime.Now;
        foreach (var pOWmsOutOrderSummary in master.POWmsOutOrderSummaries)
        {
            var flag = bRcsLocations.Where(t => t.Id == pOWmsOutOrderSummary.StartLoc).Any();
            if (!flag)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { pOWmsOutOrderSummary.Id.GetValueOrDefault() }, $"按库位出库开始位{pOWmsOutOrderSummary.StartLoc}无法创建任务 | {newDate}.");
                continue;
            }

            //货位无胎
            if (!locSkuIds.Contains(pOWmsOutOrderSummary.StartLoc))
            {
                //TODO 更新出库订单remark：记录下日志（货位已无胎）
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { pOWmsOutOrderSummary.Id.GetValueOrDefault() }, $"单叉出库,货位{pOWmsOutOrderSummary.StartLoc}无胎 | {newDate}.");
                continue;
            }

            var forkFlag = pOWcsAsrsLocHalts.Where(t => t.CrnFork == crnFork.Fork && t.LocId == pOWmsOutOrderSummary.StartLoc).Any();
            if (forkFlag)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { pOWmsOutOrderSummary.Id.GetValueOrDefault() }, $"货叉{crnFork.Fork}无法取货位{pOWmsOutOrderSummary.StartLoc}胎胚 | {newDate}.");
                continue;
            }

            var cmdTarloc = GetCmdTargetLoc(pOWmsOutOrderSummary, crnFork);
            if (cmdTarloc == 0)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { pOWmsOutOrderSummary.Id.GetValueOrDefault() }, $"目标位{pOWmsOutOrderSummary.TargetLoc}未配置异常路径 | {newDate}.");
                break;
            }

            var groupNo = K8.LSF.Client.CodeValue(new DateTime(), "GroupNo").ToInt(0);

            taskBeans.Add(new()
            {
                StartLoc = pOWmsOutOrderSummary.StartLoc,
                CmdTargetLoc = cmdTarloc,
                TaskTargetLoc = pOWmsOutOrderSummary.TargetLoc,
                Fork = crnFork,
                MasterId = pOWmsOutOrderSummary.MasterId,
                SummaryId = pOWmsOutOrderSummary.Id,
                Index = crnFork.Index,
                GroupNo = groupNo
            });
        }

        var taskIds = new List<long>();
        foreach (var item in taskBeans)
        {
            var taskId = CreateTask(item);
            if (taskId <= 0)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { item.SummaryId.GetValueOrDefault() }, $"任务创建失败({taskId}) | {newDate}");
                break;
            }
            taskIds.Add(taskId);
        }
        if (taskIds.Count > 0)
        {

            // 修改可执行状态状态
            _Task.UpdateTaskAndCmdStatusByTaskIds(taskIds, (int)EnumTaskStatus.Executable);


        }

    }
    /// <summary>
    /// 创建单叉出库任务-按条码出库
    /// </summary>
    /// <param name="master"></param>
    /// <param name="crnFork"></param>
    /// <param name="bRcsLocations"></param>
    /// <param name="pOWcsAsrsLocHalts"></param>
    /// <param name="locSkuIds"></param>
    /// <param name="equipHoldList"></param>
    public void CreateTaskSigleByProductCodeOrders(OrderSummaryGroupyMaster master, CrnForkInfo crnFork,
        List<PORcsLocation> bRcsLocations, List<POWcsAsrsLocHalt> pOWcsAsrsLocHalts, List<long?> locSkuIds,
        List<POWcsEquipLocHold> equipHoldList)
    {
        var taskBeans = new List<TaskBean>();
        DateTime newDate = DateTime.Now;
        foreach (var pOWmsOutOrderSummary in master.POWmsOutOrderSummaries)
        {
            var flag = bRcsLocations.Where(t => t.Id == pOWmsOutOrderSummary.StartLoc).Any();
            if (!flag)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { pOWmsOutOrderSummary.Id.GetValueOrDefault() }, $"按条码出库开始位{pOWmsOutOrderSummary.StartLoc}无法创建任务 | {newDate}.");
                continue;
            }

            //货位无胎
            if (!locSkuIds.Contains(pOWmsOutOrderSummary.StartLoc))
            {
                //TODO 更新出库订单remark：记录下日志（货位已无胎）
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { pOWmsOutOrderSummary.Id.GetValueOrDefault() }, $"单叉出库,货位{pOWmsOutOrderSummary.StartLoc}无胎 | {newDate}.");
                continue;
            }

            var forkFlag = pOWcsAsrsLocHalts.Where(t => t.CrnFork == crnFork.Fork && t.LocId == pOWmsOutOrderSummary.StartLoc).Any();
            if (forkFlag)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { pOWmsOutOrderSummary.Id.GetValueOrDefault() }, $"货叉{crnFork.Fork}无法取货位{pOWmsOutOrderSummary.StartLoc}胎胚 | {newDate}.");
                continue;
            }
            var cmdTarloc = GetCmdTargetByProductCode(crnFork);
            if (cmdTarloc == 0)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { pOWmsOutOrderSummary.Id.GetValueOrDefault() }, $"单叉出库,按条码出库未获取到指令目标货位 | {newDate}.");
                break;
            }

            var groupNo = K8.LSF.Client.CodeValue(new DateTime(), "GroupNo").ToInt(0);

            taskBeans.Add(new()
            {
                StartLoc = pOWmsOutOrderSummary.StartLoc,
                CmdTargetLoc = cmdTarloc,
                TaskTargetLoc = pOWmsOutOrderSummary.TargetLoc,
                Fork = crnFork,
                MasterId = pOWmsOutOrderSummary.MasterId,
                SummaryId = pOWmsOutOrderSummary.Id,
                Index = crnFork.Index,
                GroupNo = groupNo
            });
        }

        var taskIds = new List<long>();
        foreach (var item in taskBeans)
        {
            var taskId = CreateTask(item);
            if (taskId <= 0)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { item.SummaryId.GetValueOrDefault() }, $"任务创建失败({taskId}) | {newDate}");
                break;
            }
            taskIds.Add(taskId);
        }
        if (taskIds.Count > 0)
        {

            // 修改可执行状态状态
            _Task.UpdateTaskAndCmdStatusByTaskIds(taskIds, (int)EnumTaskStatus.Executable);


        }

    }
    public void CreateTaskByLocOrders(OrderSummaryGroupyMaster master, List<CrnForkInfo> crnForks)
    {
        // TODO 按库位出库验证 start_loc 是否有胎，【有：创建任务；无：修改summary备注说明一下 start_loc 无胎】
        var taskBeans = new List<TaskBean>();
        DateTime newDate = DateTime.Now;
        // 设备管理货位
        var equipHoldList = _WcsEquipLocHold.GetEquipLocHolds();
        // 停机货位
        var equipHaltList = _WcsAsrsLocHalt.GetAsrsLocHalt();
        // 开始位
        var startLocs = master.POWmsOutOrderSummaries.Select(t => t.StartLoc).ToList();
        // 位置
        var locInfos = _RcsLocation.GetAllLocationsByType((int)EnumLocType.Location).Where(t => startLocs.Contains(t.Id)).ToList();

        // 可用货叉
        var equipHold = equipHoldList.Where(t => t.LocId == master.POWmsOutOrderSummaries[0].StartLoc).FirstOrDefault();
        var forks = crnForks.Where(t => t.CrnId == equipHold?.EquipId).ToList();
        var forkCount = forks.Where(t => t.IsEnable == true).Count();
        if (forkCount == 0)
        {
            var summaryIds = master.POWmsOutOrderSummaries.Select(t => t.Id.GetValueOrDefault()).ToList();
            _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryIds, $"堆垛机{equipHold.EquipId}货叉不可用 | {newDate}.");
            return;
        }

        //通过货位ID集合获取货位与SKU（胎胚）的动态绑定关系
        var locSkuIds = _WcsLocSku.GetWcsLocSkuByLocIds(startLocs).Select(t => t.LocId).ToList();

        // 单叉
        if (forkCount == 1)
        {
            var fork = forks.Where(t => t.IsEnable == true).FirstOrDefault();
            CreateTaskSigleOrders(master, fork, locInfos, equipHaltList, locSkuIds);
            return;
        }

        var locinfoGroups = locInfos.GroupBy(t => new { t.GroupId })
           .Select(t => new
           {
               GroupId = t.Key.GroupId.Value,
               Count = t.Count(),
               LocInfos = t.OrderBy(x => x.GroupIndex).ToList()
           }).ToList();

        // 双胎，配对
        var locDouble = locinfoGroups.Where(t => t.Count == 2).ToList();
        foreach (var group in locDouble)
        {
            var groupNo = K8.LSF.Client.CodeValue(new DateTime(), "GroupNo").ToInt(0);
            foreach (var loc in group.LocInfos)
            {
                var summary = master.POWmsOutOrderSummaries.Where(t => t.StartLoc == loc.Id).FirstOrDefault();
                if (summary is null)
                {
                    break;
                }

                //货位无胎
                if (!locSkuIds.Contains(loc.Id))
                {
                    //TODO 更新出库订单remark：记录下日志（货位已无胎）
                    _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { summary.Id.GetValueOrDefault() }, $"双胎配对出库,货位{loc.Id}无胎 | {newDate}.");
                    break;
                }
                var fork = forks.Where(t => t.Index == loc.GroupIndex).FirstOrDefault();
                var cmdTarLoc = GetCmdTargetLoc(summary, fork);
                if (cmdTarLoc == 0)
                {
                    _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { summary.Id.GetValueOrDefault() }, $"按库位出库目标位{summary.TargetLoc}未配置异常路径 | {newDate}.");
                    break;
                }
                taskBeans.Add(new()
                {
                    StartLoc = summary.StartLoc,
                    CmdTargetLoc = cmdTarLoc,
                    TaskTargetLoc = summary.TargetLoc,
                    Fork = fork,
                    MasterId = summary.MasterId,
                    SummaryId = summary.Id,
                    Index = loc.GroupIndex,
                    GroupNo = groupNo
                });
            }
        }

        // 单胎，不配对
        var locSingles = locinfoGroups.Where(t => t.Count == 1).SelectMany(t => t.LocInfos).OrderBy(t => t.AxisX).ToList();
        for (int i = 0; i < locSingles.Count; i++)
        {
            var groupNo = K8.LSF.Client.CodeValue(new DateTime(), "GroupNo").ToInt(0);
            var loc = locSingles[i];
            if (loc is null)
            {
                locSingles.Remove(locSingles[i]);
                i--;
                continue;
            }
            var summary = master.POWmsOutOrderSummaries.Where(t => t.StartLoc == loc.Id).FirstOrDefault();
            if (summary is null)
            {
                locSingles.Remove(locSingles[i]);
                i--;
                continue;
            }
            //货位无胎
            if (!locSkuIds.Contains(loc.Id))
            {
                //TODO 更新出库订单remark：记录下日志（货位已无胎）
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { summary.Id.GetValueOrDefault() }, $"单胎出库,货位{loc.Id}无胎 | {newDate}.");
                i--;
                continue;
            }
            var fork1 = forks.Where(t => t.Index == loc.GroupIndex).FirstOrDefault();
            var equipHalt = equipHaltList.Where(t => t.LocId == loc.Id && t.CrnFork == fork1.Fork).FirstOrDefault();
            if (equipHalt != null)
            {
                fork1 = forks.Where(t => t.Fork != equipHalt.CrnFork).FirstOrDefault();
            }
            var cmdTarLoc = GetCmdTargetLoc(summary, fork1);
            if (cmdTarLoc == 0)
            {
                locSingles.Remove(locSingles[i]);
                i--;
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { summary.Id.GetValueOrDefault() }, $"按库位出库目标位{summary.TargetLoc}未配置异常路径 | {newDate}.");
                continue;
            }
            taskBeans.Add(new()
            {
                StartLoc = summary.StartLoc,
                CmdTargetLoc = cmdTarLoc,
                TaskTargetLoc = summary.TargetLoc,
                Fork = fork1,
                MasterId = summary.MasterId,
                SummaryId = summary.Id,
                Index = 1,
                GroupNo = groupNo
            });
            locSingles.Remove(locSingles[i]);
            i--;
            var fork2 = forks.Where(t => t.Fork != fork1.Fork).FirstOrDefault();
            for (int j = 0; j < locSingles.Count; j++)
            {
                if (locSingles[j] is null)
                {
                    continue;
                }
                var summary2 = master.POWmsOutOrderSummaries.Where(t => t.StartLoc == locSingles[j].Id).FirstOrDefault();
                if (summary2 is null)
                {
                    continue;
                }
                //货位无胎
                if (!locSkuIds.Contains(locSingles[j].Id))
                {
                    //TODO 更新出库订单remark：记录下日志（货位已无胎）
                    _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { summary2.Id.GetValueOrDefault() }, $"单胎出库,货位{locSingles[j].Id}无胎 | {newDate}.");
                    continue;
                }
                var equipHalt2 = equipHaltList.Where(t => t.LocId == locSingles[j].Id && t.CrnFork == fork2.Fork).FirstOrDefault();
                if (equipHalt2 == null)
                {
                    var cmdTarLoc2 = GetCmdTargetLoc(summary2, fork2);
                    if (cmdTarLoc2 == 0)
                    {
                        _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { summary2.Id.GetValueOrDefault() }, $"按库位出库目标位{summary2.TargetLoc}未配置异常路径 | {newDate}.");
                        continue;
                    }
                    taskBeans.Add(new()
                    {
                        StartLoc = summary2.StartLoc,
                        CmdTargetLoc = cmdTarLoc2,
                        TaskTargetLoc = summary2.TargetLoc,
                        Fork = fork2,
                        MasterId = summary2.MasterId,
                        SummaryId = summary2.Id,
                        Index = 2,
                        GroupNo = groupNo
                    });
                    locSingles.Remove(locSingles[j]);
                    break;
                }
                else
                {
                    if (equipHalt2.CrnFork != fork2.Fork)
                    {
                        var cmdTarLoc2 = GetCmdTargetLoc(summary2, fork2);
                        if (cmdTarLoc2 == 0)
                        {
                            _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { summary2.Id.GetValueOrDefault() }, $"按库位出库目标位{summary2.TargetLoc}未配置异常路径 | {newDate}.");
                            continue;
                        }
                        taskBeans.Add(new()
                        {
                            StartLoc = summary2.StartLoc,
                            CmdTargetLoc = cmdTarLoc2,
                            TaskTargetLoc = summary2.TargetLoc,
                            Fork = fork2,
                            MasterId = summary2.MasterId,
                            SummaryId = summary2.Id,
                            Index = 2,
                            GroupNo = groupNo
                        });
                        locSingles.Remove(locSingles[j]);
                        break;
                    }
                }
            }

        }

        var taskIds = new List<long>();
        foreach (var item in taskBeans)
        {
            var taskId = CreateTask(item);
            if (taskId <= 0)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { item.SummaryId.GetValueOrDefault() }, $"任务创建失败({taskId}) | {newDate}");
                break;
            }
            taskIds.Add(taskId);
        }
        if (taskIds.Count > 0)
        {

            // 修改可执行状态状态
            _Task.UpdateTaskAndCmdStatusByTaskIds(taskIds, (int)EnumTaskStatus.Executable);


        }
    }
    public void CreateTaskByProductCodeOrders(OrderSummaryGroupyMaster master, List<CrnForkInfo> crnForks)
    {
        // TODO 按条码出库验证 start_loc 是否有胎，【有：创建任务；无：修改summary备注说明一下 start_loc 无胎】
        var taskBeans = new List<TaskBean>();
        DateTime newDate = DateTime.Now;

        //非请料：执行；请料：任务数满停止，任务数不满继续 11ms
        if (_RcsEquipCuringDitch.IsCallMaterialExceed(master))
        {
            var summaryids = master.POWmsOutOrderSummaries.Select(t => t.Id.GetValueOrDefault()).ToList();
            _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, $"当前硫化排请料任务数满退出{newDate}");
            return;
        }

        //获取所有设备管理货位
        var equipHoldList = _WcsEquipLocHold.GetEquipLocHolds();
        //获取所有货叉停机货位
        var equipHaltList = _WcsAsrsLocHalt.GetAsrsLocHalt();


        var startLocs = master.POWmsOutOrderSummaries.Select(t => t.StartLoc).ToList();
        var locInfos = _RcsLocation.GetLocations().Where(t => startLocs.Contains(t.Id)).ToList();

        var equipHold = equipHoldList.Where(t => t.LocId == master.POWmsOutOrderSummaries[0].StartLoc).FirstOrDefault();
        var forks = crnForks.Where(t => t.CrnId == equipHold?.EquipId).ToList();
        var forkCount = forks.Where(t => t.IsEnable == true).Count();
        if (forkCount == 0)
        {
            var summaryIds = master.POWmsOutOrderSummaries.Select(t => t.Id.GetValueOrDefault()).ToList();
            _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryIds, $"堆垛机{equipHold.EquipId}货叉不可用 | {newDate}.");
            return;
        }

        //通过货位ID集合获取货位与SKU（胎胚）的动态绑定关系
        var locSkuIds = _WcsLocSku.GetWcsLocSkuByLocIds(startLocs).Select(t => t.LocId).ToList();

        // 单叉
        if (forkCount == 1)
        {
            var fork = forks.Where(t => t.IsEnable == true).FirstOrDefault();
            CreateTaskSigleByProductCodeOrders(master, fork, locInfos, equipHaltList, locSkuIds, equipHoldList);
            return;
        }

        var locinfoGroups = locInfos.GroupBy(t => new { GroupId = 1 })
           .Select(t => new
           {
               GroupId = t.Key.GroupId,
               Count = t.Count(),
               LocInfos = t.OrderBy(x => x.GroupIndex).ToList()
           }).ToList();



        // 双胎，配对
        var locDouble = locinfoGroups.Where(t => t.Count == 2).ToList();
        foreach (var group in locDouble)
        {
            var groupNo = K8.LSF.Client.CodeValue(new DateTime(), "GroupNo").ToInt(0);
            foreach (var loc in group.LocInfos)
            {
                var summary = master.POWmsOutOrderSummaries.Where(t => t.StartLoc == loc.Id).FirstOrDefault();
                if (summary is null)
                {
                    break;
                }

                //货位无胎
                if (!locSkuIds.Contains(loc.Id))
                {
                    //TODO 更新出库订单remark：记录下日志（货位已无胎）
                    _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { summary.Id.GetValueOrDefault() }, $"双胎配对出库,货位{loc.Id}无胎 | {newDate}.");
                    break;
                }


                var upFork = taskBeans.Where(t => t.GroupNo == groupNo).FirstOrDefault()?.Fork;
                var fork1 = forks.Where(t => t.Index == loc.GroupIndex).FirstOrDefault();
                if (upFork is not null)
                {
                    fork1 = forks.Where(t => t.Fork != upFork.Fork).FirstOrDefault();
                }

                var equipHalt = equipHaltList.Where(t => t.LocId == loc.Id && t.CrnFork == fork1.Fork).FirstOrDefault();
                if (equipHalt != null)
                {
                    fork1 = forks.Where(t => t.Fork != equipHalt.CrnFork).FirstOrDefault();
                }
                var cmdTarLoc = GetCmdTargetByProductCode(fork1);
                if (cmdTarLoc == 0)
                {
                    _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { summary.Id.GetValueOrDefault() }, $"双胎配对出库,按条码出库未获取到指令目标货位 | {newDate}.");
                    break;
                }

                if (upFork?.Fork == fork1.Fork)
                {
                    groupNo = K8.LSF.Client.CodeValue(new DateTime(), "GroupNo").ToInt(0);
                }

                taskBeans.Add(new()
                {
                    StartLoc = summary.StartLoc,
                    CmdTargetLoc = cmdTarLoc,
                    TaskTargetLoc = summary.TargetLoc,
                    Fork = fork1,
                    MasterId = summary.MasterId,
                    SummaryId = summary.Id,
                    Index = loc.GroupIndex,
                    GroupNo = groupNo
                });
            }
        }

        // 单胎，不配对
        var locSingles = locinfoGroups.Where(t => t.Count == 1).SelectMany(t => t.LocInfos).OrderBy(t => t.AxisX).ToList();
        for (int i = 0; i < locSingles.Count; i++)
        {
            var groupNo = K8.LSF.Client.CodeValue(new DateTime(), "GroupNo").ToInt(0);
            var loc = locSingles[i];
            if (loc is null)
            {
                locSingles.Remove(locSingles[i]);
                i--;
                continue;
            }
            var summary = master.POWmsOutOrderSummaries.Where(t => t.StartLoc == loc.Id).FirstOrDefault();
            if (summary is null)
            {
                locSingles.Remove(locSingles[i]);
                i--;
                continue;
            }
            //货位无胎
            if (!locSkuIds.Contains(loc.Id))
            {
                //TODO 更新出库订单remark：记录下日志（货位已无胎）
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { summary.Id.GetValueOrDefault() }, $"单胎出库,货位{loc.Id}无胎 | {newDate}.");
                i--;
                continue;
            }
            var fork1 = forks.Where(t => t.Index == loc.GroupIndex).FirstOrDefault();
            var equipHalt = equipHaltList.Where(t => t.LocId == loc.Id && t.CrnFork == fork1.Fork).FirstOrDefault();
            if (equipHalt != null)
            {
                fork1 = forks.Where(t => t.Fork != equipHalt.CrnFork).FirstOrDefault();
            }
            var cmdTarLoc = GetCmdTargetByProductCode(fork1);
            if (cmdTarLoc == 0)
            {
                locSingles.Remove(locSingles[i]);
                i--;
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { summary.Id.GetValueOrDefault() }, $"单胎出库,按条码出库未获取到指令目标货位 | {newDate}.");
                continue;
            }
            taskBeans.Add(new()
            {
                StartLoc = summary.StartLoc,
                CmdTargetLoc = cmdTarLoc,
                TaskTargetLoc = summary.TargetLoc,
                Fork = fork1,
                MasterId = summary.MasterId,
                SummaryId = summary.Id,
                Index = 1,
                GroupNo = groupNo
            });
            locSingles.Remove(locSingles[i]);
            i--;
            var fork2 = forks.Where(t => t.Fork != fork1.Fork).FirstOrDefault();
            for (int j = 0; j < locSingles.Count; j++)
            {
                if (locSingles[j] is null)
                {
                    continue;
                }
                var summary2 = master.POWmsOutOrderSummaries.Where(t => t.StartLoc == locSingles[j].Id).FirstOrDefault();
                if (summary2 is null)
                {
                    continue;
                }
                //货位无胎
                if (!locSkuIds.Contains(locSingles[j].Id))
                {
                    //TODO 更新出库订单remark：记录下日志（货位已无胎）
                    _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { summary2.Id.GetValueOrDefault() }, $"单胎出库,货位{locSingles[j].Id}无胎 | {newDate}.");
                    continue;
                }
                var equipHalt2 = equipHaltList.Where(t => t.LocId == locSingles[j].Id && t.CrnFork == fork2.Fork).FirstOrDefault();
                if (equipHalt2 == null)
                {
                    var cmdTarLoc2 = GetCmdTargetByProductCode(fork2);
                    if (cmdTarLoc2 == 0)
                    {
                        _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { summary2.Id.GetValueOrDefault() }, $"单胎出库,按条码出库未获取到指令目标货位 | {newDate}.");
                        continue;
                    }
                    taskBeans.Add(new()
                    {
                        StartLoc = summary2.StartLoc,
                        CmdTargetLoc = cmdTarLoc2,
                        TaskTargetLoc = summary2.TargetLoc,
                        Fork = fork2,
                        MasterId = summary2.MasterId,
                        SummaryId = summary2.Id,
                        Index = 2,
                        GroupNo = groupNo
                    });
                    locSingles.Remove(locSingles[j]);
                    break;
                }
                else
                {
                    if (equipHalt2.CrnFork != fork2.Fork)
                    {
                        var cmdTarLoc2 = GetCmdTargetByProductCode(fork2);
                        if (cmdTarLoc2 == 0)
                        {
                            _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { summary2.Id.GetValueOrDefault() }, $"单胎出库,按条码出库未获取到指令目标货位 | {newDate}.");
                            continue;
                        }
                        taskBeans.Add(new()
                        {
                            StartLoc = summary2.StartLoc,
                            CmdTargetLoc = cmdTarLoc2,
                            TaskTargetLoc = summary2.TargetLoc,
                            Fork = fork2,
                            MasterId = summary2.MasterId,
                            SummaryId = summary2.Id,
                            Index = 2,
                            GroupNo = groupNo
                        });
                        locSingles.Remove(locSingles[j]);
                        break;
                    }
                }
            }

        }

        var taskIds = new List<long>();
        foreach (var item in taskBeans)
        {
            var taskId = CreateTask(item);
            if (taskId <= 0)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { item.SummaryId.GetValueOrDefault() }, $"任务创建失败({taskId}) | {newDate}");
                break;
            }
            taskIds.Add(taskId);
        }
        if (taskIds.Count > 0)
        {

            // 修改可执行状态状态
            _Task.UpdateTaskAndCmdStatusByTaskIds(taskIds, (int)EnumTaskStatus.Executable);


        }
    }
    /// <summary>
    /// 根据订单明细的目标货位获取指令目标货位(按库位出库异常口)
    /// </summary>
    /// <param name="summary"></param>
    /// <param name="crnFork"></param>
    /// <returns></returns>
    private long GetCmdTargetLoc(POWmsOutOrderSummary summary, CrnForkInfo crnFork)
    {
        var netAblm = _WcsAsrsCrnAbnormalOutPut.GetAsrsCrnAbnormalOutPutByLocId(summary.TargetLoc.GetValueOrDefault());

        var crnId = netAblm?.CrnId ?? 0;
        var crnNum = _RcsEquipCrn.GetRcsEquipCrnById(crnId).Count();
        //var crnNum = _RcsEquipCrn.GetRcsEquipCrn().Where(t => t.Id == crnId)
        if (crnNum > 0)
        {
            // 立库异常口
            if (crnFork.Index == 1)
            {
                var loc = netAblm.OutputLoc1.GetValueOrDefault();
                return loc;
            }
            else
            {
                var loc = netAblm.OutputLoc2.GetValueOrDefault();
                return loc;
            }

            // return summary.TargetLoc.GetValueOrDefault();
        }
        else
        {
            // 线体异常口
            if (crnFork.Index == 1)
            {
                var loc = _WcsAsrsCrnOutPut. GetWcsAsrsCrnAbnormalOutputsByCrnId(crnFork.CrnId.GetValueOrDefault()).FirstOrDefault().OutputLoc1.GetValueOrDefault();
                //var loc = _WcsAsrsCrnOutPut.GetWcsAsrsCrnOutputByEquipId(crnFork.CrnId.GetValueOrDefault()).FirstOrDefault().OutputLoc1.GetValueOrDefault();
                return loc;
            }
            else
            {
              
                var result = _WcsAsrsCrnOutPut.GetWcsAsrsCrnAbnormalOutputsByCrnId(crnFork.CrnId.GetValueOrDefault());
                long loc = result.FirstOrDefault().OutputLoc2.GetValueOrDefault();
                //var loc = _WcsAsrsCrnOutPut.GetWcsAsrsCrnOutputByEquipId(crnFork.CrnId.GetValueOrDefault()).FirstOrDefault().OutputLoc2.GetValueOrDefault();
                return loc;
            }
        }
    }
    /// <summary>
    /// 根据订单明细的目标货位获取指令目标货位-按条码出库
    /// </summary>
    /// <param name="crnFork"></param>
    /// <returns></returns>
    private long GetCmdTargetByProductCode(CrnForkInfo crnFork)
    {
        if (crnFork.Index == 1)
        {
            var loc = _WcsAsrsCrnOutPut.GetWcsAsrsCrnOutputByEquipId(crnFork.CrnId.GetValueOrDefault()).FirstOrDefault().OutputLoc1.GetValueOrDefault();
            return loc;
        }
        else
        {
            var loc = _WcsAsrsCrnOutPut.GetWcsAsrsCrnOutputByEquipId(crnFork.CrnId.GetValueOrDefault()).FirstOrDefault().OutputLoc2.GetValueOrDefault();
            return loc;
        }
    }
    /// <summary>
    /// 创建
    /// </summary>
    /// <param name="startLoc"></param>
    /// <param name="targetLoc"></param>
    /// <param name="crnForkInfo"></param>
    /// <returns></returns>
    public long CreateTask(TaskBean taskBean, [CallerMemberNameAttribute] string MemberName = "", [CallerFilePathAttribute] string filePath = "", [CallerLineNumberAttribute] int callNumber = 0)
    {
        try
        {
            // 验证开始位是否已经创建订单
            var isTask = _Task.GetTaskByStartLoc(taskBean.StartLoc.GetValueOrDefault());
            if (isTask is not null)
            {
                return -1;
            }
            var remark = string.Empty;
            try
            {
                var path = filePath.Split("\\");

                remark = $"调用者路径{path[path.Length - 2] + "\\" + path[path.Length - 1]} -- 调用者方法名：{MemberName} -- 调用行数：{callNumber}";
            }
            catch
            {

            }
            // 修改订单
            var num = _WmsOutOrderSummary.UpdateSummaryLocAndRealCount(taskBean.SummaryId, taskBean.StartLoc, 1);
            if (num == 0)
            {
                return -2;
            }

            // 删除任务/创建任务
            _Task.BakAndDeleteCreateTaskAndCmd(taskBean.SummaryId.GetValueOrDefault());

            //OLDTODO 【已解决】绑定订单， 修改订单
            var task = _Task.CreateOutOrderTaskAndCmd(taskBean, (int)EnumTaskType.Exwarehouse, (int)EnumTaskCmdStatus.Create);
            if (task is null)
            {
                return -3;
            }
            // 修改订单状态
            _WmsOutOrderMaster.UpdateMasterStatus(taskBean.MasterId.GetValueOrDefault(), (int)EnumCodeOutOrderStatus.Execute);

            //同步MES
            //SyncMes(task);

            return task.POWcsTask.Id.GetValueOrDefault();
        }
        catch (Exception ex)
        {
            WriteLog($"异常：{ex.Message}", true);
            _WmsOutOrderSummary.RollBackSummaryLocAndRealCount(taskBean.SummaryId, $"任务创建失败:{ex.Message}", 1);
            return -5;
        }
    }
    /// <summary>
    /// 同步MES
    /// </summary>
    /// <param name="taskInfoBean"></param>
    private void SyncMes(TaskInfoBean taskInfoBean)
    {
        //推送出库订单状态(WMS->MES)
        List<PushOutOrderStatusParam> pushOutOrderStatusParams = new List<PushOutOrderStatusParam>();
        var tireBarcode = _ProdProduct.GetCodeBySkuId(taskInfoBean.POWcsTask.SkuId.GetValueOrDefault());
        pushOutOrderStatusParams.Add(new PushOutOrderStatusParam
        {
            OrderDetailId = taskInfoBean.POWcsTask.SummaryId?.ToString(),
            OrderStatus = (int)EnumPushOutOrderStatus.CreateTask,
            TireBarcode = tireBarcode
        });
        _Wms2MesService.PushOutOrderStatus(pushOutOrderStatusParams);
    }
    public List<WcsAsrsNetOutputGroup> CreateTaskRoutine(List<WcsAsrsNetOutputGroup> asrsOutInfoBeans, List<NetOutEntity> asrsNetOutputs, List<CrnOutLoc> platformLocs, List<POWcsAsrsLocHalt> wcsAsrsLocHalts,
        OrderSummaryGroupyMaster master, List<CanStock> locations)
    {
        var summaryids = master.POWmsOutOrderSummaries.Select(t => t.Id.GetValueOrDefault()).ToList();
        var newDate = DateTime.Now;

        var crnIds = platformLocs.Select(t => t.CrnId).ToList();
        var areaIds = platformLocs.Select(t => t.AreaId).ToList();
        var netOutputs = asrsNetOutputs.Where(t => crnIds.Contains(t.CrnId) && areaIds.Contains(t.AreaId)).ToList();

        if (netOutputs.Count == 0)
        {
            _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, $"未过期,站台位数量{platformLocs.Count}[可能堆垛机出库任务满],没有可选择出库路线 | {newDate}.");

            //WriteLog($"未过期,站台位数量{platformLocs.Count}[可能堆垛机出库任务满],没有可选择出库路线{newDate}.数据：{platformLocs.ToJson()}", true);
            return asrsOutInfoBeans;
        }

        foreach (var wcsAsrsNet in netOutputs)
        {
            if (wcsAsrsNet.LocationGroupInfos.Count() == 0)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, $"未过期,没有满足的库位可能 | {newDate}");
                continue;
            }

            //OLDTODO执行任务的时候验证是否有料 BIZ控制
            var noSkuLoc = platformLocs.Where(t => t.AreaId == wcsAsrsNet.AreaId && t.CrnId == wcsAsrsNet.CrnId).FirstOrDefault();
            if (noSkuLoc == null)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, $"未过期,堆垛机{wcsAsrsNet.CrnId}出库站台位未找到,可能出库任务数已满 | {newDate}.");

                //WriteLog($"未过期,{wcsAsrsNet.AreaId},{wcsAsrsNet.CrnId}出库站台位{platformLocs.Count}未找到{newDate},数据：{platformLocs.ToJson()}", true);

                continue;
            }

            // 站台
            var loc1 = noSkuLoc.ExLocInfos.Where(t => t.Index == 1).FirstOrDefault();
            var loc2 = noSkuLoc.ExLocInfos.Where(t => t.Index == 2).FirstOrDefault();
            // 查询数量任务数量
            var taskCount = _TaskCmd.GetTaskCmdCountByLocs(new()
            {
                loc1.LocId.GetValueOrDefault(),
                loc2.LocId.GetValueOrDefault()
            });
            if (taskCount >= noSkuLoc.TaskCount)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, $"未过期,出库任务数{taskCount} >= 任务限制{noSkuLoc.TaskCount}已满 | {newDate}");
                continue;
            }


            // 堆垛机负责立库有满足条件物料
            var locs = locations.Where(t => t.CrnId == wcsAsrsNet.CrnId).FirstOrDefault();
            if (locs == null)
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, $"未过期,满足出库立库未找到 | {newDate}");
                continue;
            }
            var limitMaterialIds = wcsAsrsNet.LocationGroupInfos.Select(x => x.MaterialId).ToList();

            // 货叉(一个或两个货叉)
            var crnForkInfos = wcsAsrsNet.NetOutPut.CrnForkInfo; // 货叉【可用、不可用都包含】

            // 获取取货位
            var startLocs = new List<LocationInfo>();
            var orderSummaries = master.POWmsOutOrderSummaries.OrderBy(t => t.SummaryIndex).ToList();
            var summaryCount = orderSummaries.Count;

            var summary1 = orderSummaries.FirstOrDefault();
            var summary2 = orderSummaries.LastOrDefault();

            var materialId1 = summary1?.MaterialId;
            var materialId2 = summary2?.MaterialId;

            //OLDTODO 两个货叉可用，同时去两个不成对立库取货，可能有一个货位 货叉过不去。
            if (summaryCount == 1)
            {
                SingleRoute(ref startLocs, wcsAsrsNet.LocationGroupInfos, summary1, wcsAsrsLocHalts, crnForkInfos);
            }
            else if (summaryCount == 2)
            {
                if (materialId1 != materialId2)
                {

                    var summaryFir = orderSummaries.Where(t => limitMaterialIds.Contains(t.MaterialId)).OrderBy(t => t.SummaryIndex).FirstOrDefault();
                    var summarySec = orderSummaries.Where(t => t.Id != summaryFir.Id).FirstOrDefault();
                    // 物料不想同
                    // 1、双库位满足两个不同物料  getlocaltion需要匹配货叉
                    DoubleDifferentDoubleGoodsV2(ref startLocs, wcsAsrsNet.LocationGroupInfos, locs.LocationGroupInfos, crnForkInfos, summaryFir, summarySec, wcsAsrsLocHalts);

                    if (startLocs.Count == 0 || startLocs.Count != summaryCount)
                    {
                        startLocs.Clear();

                        DoubleDifferentGoodsRoute(ref startLocs, wcsAsrsNet.LocationGroupInfos, summaryFir, wcsAsrsLocHalts, crnForkInfos);

                        DoubleDifferentGoodsRoute(ref startLocs, locs.LocationGroupInfos, summarySec, wcsAsrsLocHalts, crnForkInfos);
                    }
                }
                else
                {
                    // 物料相同
                    // 1、双库位满足两个相同物料
                    DoubleSameDoubleGoods(ref startLocs, wcsAsrsNet.LocationGroupInfos, locs.LocationGroupInfos, wcsAsrsLocHalts, crnForkInfos, summary1, summary2);

                    if (startLocs.Count == 0 || startLocs.Count != summaryCount)
                    {
                        startLocs.Clear();

                        DoubleSameGoodsRoute(ref startLocs, wcsAsrsNet.LocationGroupInfos, summary1, wcsAsrsLocHalts, crnForkInfos);

                        DoubleSameGoodsRoute(ref startLocs, locs.LocationGroupInfos, summary2, wcsAsrsLocHalts, crnForkInfos);
                    }
                }
            }

            if (startLocs.Count != summaryCount)
            {
                var prodMaterial = _ProdMaterial.GetMaterialById(materialId1.GetValueOrDefault());
                var spec = prodMaterial?.Spec;
                prodMaterial = _ProdMaterial.GetMaterialById(materialId2.GetValueOrDefault());
                var spec1 = prodMaterial?.Spec;
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, $"未过期,{spec},{spec1}满足出库货位{startLocs.Count} 与请料单数量{summaryCount}不一致 | {newDate}");
                continue;
            }

            var message = "";
            // 判断是否能到 27 列
            for (var i = 0; i < startLocs.Count; i++)
            {
                var flag = wcsAsrsLocHalts.Where(t => t.LocId == startLocs[i].Id && t.CrnFork == startLocs[i].Fork.Fork).Any();
                if (flag)
                {
                    message += $"未过期,停机货位：{wcsAsrsLocHalts.Count}货叉{startLocs[i].Fork.Fork}无法到达货位{startLocs[i].Id} ———";
                }
            }
            if (!string.IsNullOrWhiteSpace(message))
            {
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, $"提示:{message} | {newDate}");
                continue;
            }

            // 创建任务
            var taskBeans = new List<TaskBean>();
            startLocs = startLocs.OrderBy(t => t.GroupIndex).ToList(); // 排序五种情况 (2),(1),(1,2),(1,1),(2,2)

            var groupNo = K8.LSF.Client.CodeValue(new DateTime(), "GroupNo").ToInt(0);
            var forkCount = crnForkInfos.Where(t => t.IsEnable == true).Count(); // 可用货叉数

            for (var i = 0; i < startLocs.Count; i++)
            {
                // 放胎位
                var loc = startLocs[i].Fork.Index == 1 ? loc1 : loc2;

                if (forkCount == 1 && i == 1)
                {
                    // 单货叉可用
                    groupNo = K8.LSF.Client.CodeValue(new DateTime(), "GroupNo").ToInt(0);
                }

                taskBeans.Add(new()
                {
                    StartLoc = startLocs[i].Id,
                    CmdTargetLoc = loc.LocId.GetValueOrDefault(),
                    TaskTargetLoc = startLocs[i].Summary.TargetLoc,
                    Fork = startLocs[i].Fork,
                    MasterId = startLocs[i].Summary.MasterId,
                    SummaryId = startLocs[i].Summary.Id,
                    Index = startLocs[i].Summary.SummaryIndex,
                    GroupNo = groupNo,
                });
            }

            // 创建任务
            var taskIds = new List<long>();
            foreach (var item in taskBeans)
            {
                var taskId = CreateTask(item);
                if (taskId <= 0)
                {
                    _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { item.SummaryId.GetValueOrDefault() }, $"任务创建失败({taskId}) | {newDate}");
                    break;
                }
                taskIds.Add(taskId);
            }
            if (taskIds.Count > 0)
            {
                // 修改可执行状态状态
                _Task.UpdateTaskAndCmdStatusByTaskIds(taskIds, (int)EnumTaskStatus.Executable);
                var forks = startLocs.Select(t => t.Fork.Fork).ToList();

                //OLDTODO[临时删除] 删除(包含fork1, fork2 货叉)可用堆垛机出库路线
                var deletes = asrsOutInfoBeans.Where(t => t.CrnForkInfo.Select(x => forks.Contains(x.Fork)).Any()).ToList();
                deletes.ForEach(t =>
                {
                    asrsOutInfoBeans.Remove(t);
                });
                break;
            }
        }

        return asrsOutInfoBeans;
    }


    public List<WcsAsrsNetOutputGroup> CreateTaskRoutineV2(List<WcsAsrsNetOutputGroup> asrsOutInfoBeans,
        List<NetOutEntity> asrsNetOutputs, List<CrnOutLoc> platformLocs, List<POWcsAsrsLocHalt> wcsAsrsLocHalts,
        OrderSummaryGroupyMaster master, List<CanStock> locations)
    {
        //WriteLog($"CreateTaskRoutineV2-111", true);
        var summaryids = master.POWmsOutOrderSummaries.Select(t => t.Id.GetValueOrDefault()).ToList();
        var newDate = DateTime.Now;


        string summaryRemark = null;

        ////在此处把任务数算出来 出超期胎时根据任务数排序
        //foreach (var wcsAsrsNet in asrsNetOutputs)
        //{
        //    if (wcsAsrsNet.IsTimeOut == 1)
        //    {
        //        var noSkuLoc = platformLocs.Where(t => t.AreaId == wcsAsrsNet.AreaId && t.CrnId == wcsAsrsNet.CrnId).FirstOrDefault();
        //        if (noSkuLoc == null)
        //        {
        //            //summaryRemark = $"未过期,区域{timeoutWcsAsrsNet.AreaId}堆垛机{timeoutWcsAsrsNet.CrnId}出库站台位未找到,可能出库任务数已满 | {newDate}";
        //            //_WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, $"未过期,区域{wcsAsrsNet.AreaId}堆垛机{wcsAsrsNet.CrnId}出库站台位未找到,可能出库任务数已满 | {newDate}");
        //            continue;
        //        }
        //        var outLoc1 = noSkuLoc.ExLocInfos.Where(t => t.Index == 1).FirstOrDefault();
        //        var outLoc2 = noSkuLoc.ExLocInfos.Where(t => t.Index == 2).FirstOrDefault();
        //        // 查询数量任务数量
        //        var taskCount = _TaskCmd.GetTaskCmdCountByLocs(new()
        //        {
        //            outLoc1.LocId.GetValueOrDefault(),
        //            outLoc2.LocId.GetValueOrDefault()
        //        });
        //        wcsAsrsNet.TaskCount = taskCount;
        //    }

        //}
        //asrsNetOutputs = asrsNetOutputs.OrderByDescending(t => t.IsTimeOut)
        //    .ThenBy(t => t.TaskCount)
        //    .ThenBy(t => t.RelateScore)
        //    .ToList();

        foreach (var wcsAsrsNet in asrsNetOutputs)
        {

            if (wcsAsrsNet.LocationGroupInfos.Count() == 0)
            {
                summaryRemark = $"未过期,没有满足的库位 | {newDate}";
                WriteLog(summaryRemark, true);
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, $"未过期,没有满足的库位可能 | {newDate}");
                continue;
            }

            //OLDTODO执行任务的时候验证是否有料 BIZ控制
            var noSkuLoc = platformLocs.Where(t => t.AreaId == wcsAsrsNet.AreaId && t.CrnId == wcsAsrsNet.CrnId).FirstOrDefault();
            if (noSkuLoc == null)
            {
                summaryRemark = $"未过期,区域{wcsAsrsNet.AreaId}堆垛机{wcsAsrsNet.CrnId}出库站台位未找到,可能出库任务数已满 | {newDate}";
                WriteLog(summaryRemark, true);
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, $"未过期,区域{wcsAsrsNet.AreaId}堆垛机{wcsAsrsNet.CrnId}出库站台位未找到,可能出库任务数已满 | {newDate}");
                continue;
            }
            //WriteLog($"出库33321243", true);
            // 站台
            var outLoc1 = noSkuLoc.ExLocInfos.Where(t => t.Index == 1).FirstOrDefault();
            var outLoc2 = noSkuLoc.ExLocInfos.Where(t => t.Index == 2).FirstOrDefault();

            if (outLoc1 is null)
            {
                outLoc1 = noSkuLoc.ExLocInfos.Where(t => t.Index == 3).FirstOrDefault();
                outLoc2 = noSkuLoc.ExLocInfos.Where(t => t.Index == 4).FirstOrDefault();
            }

            // 查询数量任务数量
            var taskCount = _TaskCmd.GetTaskCmdCountByLocs(new()
            {
                outLoc1.LocId.GetValueOrDefault(),
                outLoc2.LocId.GetValueOrDefault()
            });
            //超期胎的任务数-4 多4个任务缓存数
            if (wcsAsrsNet.IsTimeOut == 1)
            {
                taskCount = taskCount - 4;
            }
            if (taskCount >= noSkuLoc.TaskCount)
            {
                //WriteLog($"出库出库任务数{asrsNetOutputs.Count()} 满{asrsNetOutputs.ToJson()}", true);
                //WriteLog($"出库出库任务数满订单为{summaryids.ToJson()}", true);

                //noCrnList.Add(wcsAsrsNet.CrnId ?? 0);
                summaryRemark = $"未过期,堆垛机{wcsAsrsNet.CrnId},路线数{asrsNetOutputs.Count()},出库任务订单{summaryids.ToJson()} 出库任务数{taskCount} >= 任务限制{noSkuLoc.TaskCount}已满 | {newDate}";
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, summaryRemark);
                //if (asrsNetOutputs.Count == 1) {

                //    throw new NotImplementedException();
                //}
                // 修改可执行状态状态
                var crn = _RcsEquipCrn.GetCrnForkById(wcsAsrsNet.CrnId);
                var forks = new List<long?> { crn.CrnFork1, crn.CrnFork2 };
                for (int i = 0; i < asrsOutInfoBeans.Count; i++)
                {
                    var flag = asrsOutInfoBeans[i].CrnForkInfo.Where(t => forks.Contains(t.Fork)).Any();
                    if (!flag)
                    {
                        continue;
                    }
                    asrsOutInfoBeans.Remove(asrsOutInfoBeans[i]);
                    i--;
                }
                continue;
            }

            //WriteLog($"出库3332158", true);

            // 堆垛机负责立库有满足条件物料
            var locs = locations.Where(t => t.CrnId == wcsAsrsNet.CrnId).FirstOrDefault();
            if (locs == null)
            {
                summaryRemark = $"未过期,满足出库立库未找到 | {newDate}";
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, summaryRemark);
                continue;
            }
            var limitMaterialIds = wcsAsrsNet.LocationGroupInfos.Select(x => x.MaterialId).Distinct().ToList();
            //WriteLog($"出库3332168", true);
            // 货叉(一个或两个货叉)
            var crnForkInfos = wcsAsrsNet.NetOutPut.CrnForkInfo; // 货叉【可用、不可用都包含】

            // 获取取货位
            var startLocs = new List<LocationInfo>();
            var orderSummaries = master.POWmsOutOrderSummaries.OrderBy(t => t.SummaryIndex).ToList();
            var summaryCount = orderSummaries.Count;

            var summary1 = orderSummaries.FirstOrDefault();
            var summary2 = orderSummaries.LastOrDefault();

            var materialId1 = summary1?.MaterialId;
            var materialId2 = summary2?.MaterialId;
            //WriteLog($"出库3332182", true);
            //OLDTODO 两个货叉可用，同时去两个不成对立库取货，可能有一个货位 货叉过不去。
            if (summaryCount == 1)
            {
                //WriteLog($"出库3332185", true);
                SingleRoute(ref startLocs, wcsAsrsNet.LocationGroupInfos, summary1, wcsAsrsLocHalts, crnForkInfos);
                //WriteLog($"出库3332188", true);
            }
            else if (summaryCount == 2)
            {
                //WriteLog($"出库3332192", true);
                if (materialId1 != materialId2)
                {

                    var summaryFir = orderSummaries.Where(t => limitMaterialIds.Contains(t.MaterialId)).OrderBy(t => t.SummaryIndex).FirstOrDefault();
                    var summarySec = orderSummaries.Where(t => t.Id != summaryFir.Id).FirstOrDefault();
                    //WriteLog($"出库3332198", true);
                    // 物料不想同
                    // 1、双库位满足两个不同物料  getlocaltion需要匹配货叉
                    DoubleDifferentDoubleGoodsV2(ref startLocs, wcsAsrsNet.LocationGroupInfos, locs.LocationGroupInfos, crnForkInfos, summaryFir, summarySec, wcsAsrsLocHalts);
                    //WriteLog($"出库3332202", true);
                    if (startLocs.Count == 0 || startLocs.Count != summaryCount)
                    {
                        startLocs.Clear();
                        //WriteLog($"出库3332206", true);
                        DoubleDifferentGoodsRoute(ref startLocs, wcsAsrsNet.LocationGroupInfos, summaryFir, wcsAsrsLocHalts, crnForkInfos);
                        //WriteLog($"出库3332208", true);
                        DoubleDifferentGoodsRoute(ref startLocs, locs.LocationGroupInfos, summarySec, wcsAsrsLocHalts, crnForkInfos);
                        //WriteLog($"出库3332210", true);
                    }
                }
                else
                {
                    //WriteLog($"出库3332215", true);
                    // 物料相同
                    // 1、双库位满足两个相同物料
                    DoubleSameDoubleGoods(ref startLocs, wcsAsrsNet.LocationGroupInfos, locs.LocationGroupInfos, wcsAsrsLocHalts, crnForkInfos, summary1, summary2);
                    //WriteLog($"出库3332219", true);
                    if (startLocs.Count == 0 || startLocs.Count != summaryCount)
                    {
                        startLocs.Clear();
                        //WriteLog($"出库3332223", true);
                        DoubleSameGoodsRoute(ref startLocs, wcsAsrsNet.LocationGroupInfos, summary1, wcsAsrsLocHalts, crnForkInfos);
                        //WriteLog($"出库3332225", true);
                        DoubleSameGoodsRoute(ref startLocs, locs.LocationGroupInfos, summary2, wcsAsrsLocHalts, crnForkInfos);
                        //WriteLog($"出库3332227", true);
                    }
                }
            }
            //WriteLog($"出库3332231", true);
            if (startLocs.Count != summaryCount)
            {
                var prodMaterial = _ProdMaterial.GetMaterialById(materialId1.GetValueOrDefault());
                var spec = prodMaterial?.Spec;
                prodMaterial = _ProdMaterial.GetMaterialById(materialId2.GetValueOrDefault());
                var spec1 = prodMaterial?.Spec;

                summaryRemark = $"未过期,{spec},{spec1}满足出库货位{startLocs.Count} 与请料单数量{summaryCount}不一致 | {newDate}";
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, summaryRemark);
                continue;
            }
            //WriteLog($"出库3332241", true);
            var message = "";
            // 判断是否能到 27 列
            List<LocationInfo> haltStartLoc = new();
            for (var i = 0; i < startLocs.Count; i++)
            {
                var flag = wcsAsrsLocHalts.Where(t => t.LocId == startLocs[i].Id && t.CrnFork == startLocs[i].Fork.Fork).Any();
                if (flag)
                {

                    haltStartLoc.Add(startLocs[i]);
                    //startLocs.Remove(startLoc);
                    message += $"未过期,停机货位：{wcsAsrsLocHalts.Count}货叉{startLocs[i].Fork.Fork}无法到达货位{startLocs[i].Id} ———";
                }

                //var flag = wcsAsrsLocHalts.Where(t => t.LocId != startLocs[i].Id || t.CrnFork != startLocs[i].Fork.Fork).Any();
                //if (!flag)
                //{
                //    message += $"未过期,停机货位：{wcsAsrsLocHalts.Count}货叉{startLocs[i].Fork.Fork}无法到达货位{startLocs[i].Id} ———";
                //}
            }
            startLocs.AddRange(haltStartLoc);

            if (!string.IsNullOrWhiteSpace(message))
            {
                summaryRemark = $"提示:{message} | {newDate}";
                _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, summaryRemark);
                continue;
            }
            //if (!startLocs.Any())
            //{
            //    summaryRemark = $"提示:{message} | {newDate}";
            //    //     _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, summaryRemark);
            //    continue;
            //}


            //WriteLog($"出库3332257", true);

            // 创建任务
            var taskBeans = new List<TaskBean>();
            startLocs = startLocs.OrderBy(t => t.GroupIndex).ToList(); // 排序五种情况 (2),(1),(1,2),(1,1),(2,2)

            //startLocs.Where(t=> wcsAsrsLocHalts.Select(t.LocId) Contains())
            var startLocCount = startLocs.Count(); // 出库任务数量
            var startLocForkCount = startLocs.Select(t => t.Fork.Fork).Distinct().Count(); // 负责出库货叉数量
            //WriteLog($"出库3332264", true);
            var groupNo = K8.LSF.Client.CodeValue(new DateTime(), "GroupNo").ToInt(0);
            var forkCount = crnForkInfos.Where(t => t.IsEnable == true).Count(); // 可用货叉数
            //WriteLog($"出库3332267", true);
            for (var i = 0; i < startLocs.Count; i++)
            {
                // 放胎位
                var loc = startLocs[i].Fork.Index == 1 ? outLoc1 : outLoc2;

                if (forkCount == 1 && i == 1 || (startLocCount != startLocForkCount))
                {
                    // 单货叉可用
                    groupNo = K8.LSF.Client.CodeValue(new DateTime(), "GroupNo").ToInt(0);
                }

                taskBeans.Add(new()
                {
                    StartLoc = startLocs[i].Id,
                    CmdTargetLoc = loc.LocId.GetValueOrDefault(),
                    TaskTargetLoc = startLocs[i].Summary.TargetLoc,
                    Fork = startLocs[i].Fork,
                    MasterId = startLocs[i].Summary.MasterId,
                    SummaryId = startLocs[i].Summary.Id,
                    Index = startLocs[i].Summary.SummaryIndex,
                    GroupNo = groupNo,
                    StartTaskType = 2,

                });
            }
            //WriteLog($"出库3332291", true);

            // 创建任务
            var taskIds = new List<long>();
            foreach (var item in taskBeans)
            {
                var taskId = CreateTask(item);
                if (taskId <= 0)
                {
                    _WmsOutOrderSummary.RollBackSummaryLocAndRealCount(item.SummaryId, $"任务创建失败{taskId}", 1);
                    break;
                }
                else
                {
                    _WmsOutOrderSummary.UpdateOrderSummaryRemark(new() { item.SummaryId.GetValueOrDefault() }, $"任务创建成功({taskId}) | {newDate}");

                    //创建成功后更新订单的库存数量
                    try
                    {
                        var allLoc = locations.Sum(t => t.LocationGroupInfos.Count);
                        _WmsOutOrderSummary.UpdateOutOrderSumaryInventory(item.SummaryId ?? 0, allLoc, locs.LocationGroupInfos.Count, locs.CrnId ?? 0, taskId);
                    }
                    catch (Exception ex)
                    {

                    }

                }
                noSkuLoc.NowCount++; // 增加一个任务
                taskIds.Add(taskId);
            }
            //WriteLog($"出库3332310", true);
            if (taskIds.Count > 0)
            {
                // 修改可执行状态状态
                _Task.UpdateTaskAndCmdStatusByTaskIds(taskIds, (int)EnumTaskStatus.Executable);
                var forks = startLocs.Select(t => t.Fork.Fork).ToList();

                //OLDTODO[临时删除] 删除(包含fork1, fork2 货叉)可用堆垛机出库路线
                for (int i = 0; i < asrsOutInfoBeans.Count; i++)
                {
                    var flag = asrsOutInfoBeans[i].CrnForkInfo.Where(t => forks.Contains(t.Fork)).Any();
                    if (!flag)
                    {
                        continue;
                    }
                    asrsOutInfoBeans.Remove(asrsOutInfoBeans[i]);
                    i--;
                }
                break;
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(summaryRemark))
                {
                    _WmsOutOrderSummary.UpdateOrderSummaryRemark(summaryids, summaryRemark);
                }
            }
            //WriteLog($"出库3332330", true);
        }

        return asrsOutInfoBeans;
    }


}
